/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package myatm;

public class ATM {

	private boolean currentCardUnlocked = false;
	private double money;
	private Card currentCard;

    //Можно задавать количество денег в банкомате
	public static ATM getInstance(double withAmountOfMoney) {
		return new ATM(withAmountOfMoney);
	}

    private ATM(double moneyInATM) {
	    if (moneyInATM >= 0) {
	        money = moneyInATM;
	    } else {
		    throw new UnsupportedOperationException
				    ("Can't create an ATM with negative amount of money");
	    }
    }

    public double getMoneyInATM() {
        throwExnIfLocked();
	    return money;
    }
        
    // С вызова данного метода начинается работа с картой.
    // Метод принимает карту и пин-код, проверяет пин-код карты и не заблокирована ли она
    // Если неправильный пин-код или карточка заблокирована, возвращаем false.
    // При этом вызов всех последующих методов у ATM с данной картой
    // должен генерировать исключение NoCardInserted
    public boolean validateCard(Card card, int pinCode) {
	    if (card != null) {
		    if (currentCard == null || currentCard != card) {
			    currentCard = card;
		    }
		    currentCardUnlocked = card.checkPin(pinCode);
		    return currentCardUnlocked;
	    } else {
            throw new NullPointerException();
         }

    }
    
    //Возвращает сколько денег есть на счету
    public double checkBalance() {
	    throwExnIfLocked();
	    return currentCard.getAccount().getBalance();
    }

	private void throwExnIfLocked() {
		if (!currentCardUnlocked) {
			throw new UnsupportedOperationException("The card is locked or the PIN was invalid");
		}
	}

	//Метод для снятия указанной суммы
    //Метод возвращает сумму, которая у клиента осталась на счету после снятия
    //Кроме проверки счета, метод так же должен проверять достаточно ли денег в самом банкомате
    //Если недостаточно денег на счете, то должно генерироваться исключение NotEnoughMoneyInAccount 
    //Если недостаточно денег в банкомате, то должно генерироваться исключение NotEnoughMoneyInATM 
    //При успешном снятии денег, указанная сумма должна списываться со счета,
    // и в банкомате должно уменьшаться количество денег
    public double getCash(double amount) {
        throwExnIfLocked();
	    if (Double.compare(amount, 0) < 0) {
		    throw new UnsupportedOperationException("Can't get negative amount");
	    }
	    double currentBalance = currentCard.getAccount().getBalance();
		if (Double.compare(money, amount) < 0) {
			throw new UnsupportedOperationException("Not enough money in ATM");
		} else if (Double.compare(currentBalance, amount) < 0) {
			throw new UnsupportedOperationException("Not enough money in account");
	    } else {
			money -= amount;
			return currentBalance - currentCard.getAccount().withdraw(amount);
		}
    }
}
